from fastapi import APIRouter, Depends, HTTPException, status, Request, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from app.database.database import get_db
from app.models.models import SysUser, SysMenu
from app.schemas.schemas import MenuResponse, MenuCreate, MenuUpdate, MenuTreeNode
from app.utils.auth import get_current_active_user
from app.utils.menu_utils import build_menu_tree
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, JSONResponse

router = APIRouter()
templates = Jinja2Templates(directory="app/templates")

# 页面路由 - 返回HTML页面
@router.get("/menus", response_class=HTMLResponse)
async def get_menus_page(request: Request):
    return templates.TemplateResponse("menus.html", {"request": request})

# API路由 - 返回JSON数据
@router.get("/api/menus")
async def get_menus(
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user),
    skip: int = 0, 
    limit: int = 100,
    name: Optional[str] = None
):
    if current_user.is_admin == 0:
        raise HTTPException(status_code=403, detail="无权访问")
    
    query = db.query(SysMenu)
    if name:
        query = query.filter(SysMenu.name.like(f"%{name}%"))
    
    total = query.count()
    menus = query.offset(skip).limit(limit).all()
    
    total_pages = (total + limit - 1) // limit  # 计算总页数（向上取整）
    current_page = skip // limit + 1 if skip > 0 else 1  # 计算当前页码
    
    # 转换menus为字典列表，以便添加分页信息
    menu_list = []
    for menu in menus:
        menu_dict = {
            "id": menu.id,
            "pid": menu.pid,
            "name": menu.name,
            "code": menu.code,
            "path": menu.path,
            "icon": menu.icon,
            "is_active": menu.is_active,
            "created_at": menu.created_at,
            "updated_at": menu.updated_at,
        }
        menu_list.append(menu_dict)
    
    # 返回带分页信息的响应
    return {
        "items": menu_list,
        "total": total,
        "page": current_page,
        "pages": total_pages,
        "size": limit
    }

@router.get("/api/menus/tree", response_model=List[MenuTreeNode])
async def get_menu_tree(
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    menu_items = db.query(SysMenu).all()
    tree = build_menu_tree(menu_items)
    return tree

@router.get("/api/menus/user", response_model=dict)
async def get_user_menus(
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    """获取当前登录用户的菜单"""
    all_menus = []
    
    # 如果是管理员，获取所有激活的菜单
    if current_user.is_admin == 1:
        all_menus = db.query(SysMenu).filter(SysMenu.is_active == 1).all()
    # 否则，获取用户特定的菜单
    elif current_user.menu_json:
        import json
        try:
            menu_ids = json.loads(current_user.menu_json)
            all_menus = db.query(SysMenu).filter(SysMenu.id.in_(menu_ids), SysMenu.is_active == 1).all()
        except:
            all_menus = []
    
    menu_tree = build_menu_tree(all_menus)
    return {"menu_tree": menu_tree}

@router.get("/api/menus/{menu_id}", response_model=MenuResponse)
async def get_menu(
    menu_id: int, 
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    if current_user.is_admin == 0:
        raise HTTPException(status_code=403, detail="无权访问")
    
    menu = db.query(SysMenu).filter(SysMenu.id == menu_id).first()
    if not menu:
        raise HTTPException(status_code=404, detail="菜单不存在")
    return menu

@router.post("/api/menus", response_model=MenuResponse)
async def create_menu(
    menu: MenuCreate, 
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    if current_user.is_admin == 0:
        raise HTTPException(status_code=403, detail="无权访问")
    
    # 检查父菜单是否存在
    if menu.pid != 0:  # pid为0表示顶级菜单
        parent_menu = db.query(SysMenu).filter(SysMenu.id == menu.pid).first()
        if not parent_menu:
            raise HTTPException(status_code=404, detail="父菜单不存在")
    
    db_menu = SysMenu(**menu.dict())
    db.add(db_menu)
    db.commit()
    db.refresh(db_menu)
    return db_menu

@router.put("/api/menus/{menu_id}", response_model=MenuResponse)
async def update_menu(
    menu_id: int, 
    menu_update: MenuUpdate, 
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    if current_user.is_admin == 0:
        raise HTTPException(status_code=403, detail="无权访问")
    
    db_menu = db.query(SysMenu).filter(SysMenu.id == menu_id).first()
    if not db_menu:
        raise HTTPException(status_code=404, detail="菜单不存在")
    
    # 检查父菜单是否存在
    if menu_update.pid is not None and menu_update.pid != 0:
        parent_menu = db.query(SysMenu).filter(SysMenu.id == menu_update.pid).first()
        if not parent_menu:
            raise HTTPException(status_code=404, detail="父菜单不存在")
        
        # 防止将菜单设置为自己的子菜单
        if menu_update.pid == menu_id:
            raise HTTPException(status_code=400, detail="不能将菜单设置为自己的子菜单")
    
    update_data = menu_update.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_menu, key, value)
    
    db.commit()
    db.refresh(db_menu)
    return db_menu

@router.delete("/api/menus/{menu_id}")
async def delete_menu(
    menu_id: int, 
    db: Session = Depends(get_db), 
    current_user: SysUser = Depends(get_current_active_user)
):
    if current_user.is_admin == 0:
        raise HTTPException(status_code=403, detail="无权访问")
    
    # 检查是否有子菜单
    children = db.query(SysMenu).filter(SysMenu.pid == menu_id).all()
    if children:
        raise HTTPException(status_code=400, detail="请先删除子菜单")
    
    db_menu = db.query(SysMenu).filter(SysMenu.id == menu_id).first()
    if not db_menu:
        raise HTTPException(status_code=404, detail="菜单不存在")
    
    db.delete(db_menu)
    db.commit()
    return {"message": "菜单已删除"} 